use crate::client::client_manager::{ClientManager, GrpcClient};
use anyhow::Result;
use axum::{
    extract::{Json, Path, State},
    response::Json as AxumJson,
    routing::{get, post},
    Router,
};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use std::thread::sleep;
use std::time::Duration;
use tonic::transport::Channel;
use tracing::info;
use crate::server::grpc_server::user_service::GetUserRequest;
use crate::server::grpc_server::user_service::user_service_client::UserServiceClient;

#[derive(Clone)]
pub struct AppState {
    pub client_manager: Arc<ClientManager>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct WebUser {
    pub id: String,
    pub name: String,
    pub email: String,
}

#[derive(Clone)]
pub struct UserClient(pub UserServiceClient<Channel>);

impl GrpcClient for UserClient {
    fn from_channel(channel: Channel) -> Self {
        UserClient(UserServiceClient::new(channel))
    }
}


pub async fn create_web_server(client_manager: Arc<ClientManager>) -> Result<Router> {
    let user_client = match client_manager
        .create_client_with_retry::<UserClient>("user_service")
        .await
    {
        Ok(client) => client,
        Err(e) => {
            tracing::error!("Failed to create user client after retries: {}", e);
            return Err(e.into());
        }
    };

    let user_service_client = user_client.0;

    let app = Router::new()
        .route("/", get(root))
        .route("/health", get(health_check))
        .route("/users/{id}", get(get_user_handler))
        .route("/users_p/{id}", get(get_user_broken_pipe))
        .route("/users", post(create_user_handler))
        .route("/stats", get(get_stats_handler))
        .with_state(user_service_client);

    Ok(app)
}

async fn root() -> &'static str {
    "Axum + Tonic gRPC Connection Pool Server"
}

async fn health_check() -> AxumJson<serde_json::Value> {
    AxumJson(serde_json::json!({
        "status": "healthy",
        "timestamp": chrono::Utc::now().to_rfc3339()
    }))
}

async fn get_user_handler(
    State(mut user_service_client): State<UserServiceClient<Channel>>,
    Path(user_id): Path<String>,
) -> AxumJson<serde_json::Value> {
    let request = GetUserRequest { user_id };

    let request_future = user_service_client.get_user(request);

    let user = request_future.await.unwrap().into_inner().user.unwrap();

    tokio::time::sleep(Duration::from_millis(500)).await;

    AxumJson(serde_json::json!({
        "user": {
            "id": user.id,
            "name": user.name,
            "email": user.email
        }
    }))
}

async fn get_user_broken_pipe(
    State(mut user_service_client): State<UserServiceClient<Channel>>,
    Path(user_id): Path<String>,
) -> () {
    let request = GetUserRequest { user_id };

    let request_future = user_service_client.get_user(request);

    drop(request_future);
    info!("Dropped connection future - this may cause broken pipe on server side");
}

async fn create_user_handler(
    State(user_client): State<UserServiceClient<Channel>>,
    Json(payload): Json<WebUser>,
) -> AxumJson<serde_json::Value> {
    AxumJson(serde_json::json!({
        "message": "User created successfully",
        "user": payload
    }))
}

async fn get_stats_handler(State(user_client): State<UserServiceClient<Channel>>) -> AxumJson<serde_json::Value> {
    AxumJson(serde_json::json!({
        "connections": 10,
        "active": 5,
        "errors": 2
    }))
}
